home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / dev / gcc / libnix.lha / gnu / lib / libnix / sources.lha / nix / locale / setlocale.c < prev   
Encoding:
C/C++ Source or Header  |  1999-07-24  |  5.2 KB  |  196 lines

  1. #include <libraries/locale.h>
  2. #include <locale.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #ifdef __GNUC__ /* This is very sad :-( */
  6. #undef BITSPERBYTE
  7. #undef MAXINT
  8. #undef MININT
  9. #endif
  10. #include <limits.h>
  11. #ifdef __GNUC__
  12. #include <inline/exec.h>
  13. #include <inline/locale.h>
  14. #endif
  15. #include <strsup.h>
  16. #include <stabs.h>
  17.  
  18. struct LocaleBase *LocaleBase=NULL;
  19. extern char __localename[];
  20. extern struct Locale *__localevec[];
  21.  
  22. /* for LC_CTYPE */
  23. extern const unsigned char __ctype[];
  24. extern const unsigned char *_ctype_;
  25. static unsigned char *ctype;
  26.  
  27. /* for LC_NUMERIC */
  28. extern unsigned char *__decimalpoint;
  29.  
  30. /* for LC_TIME */
  31. extern long __gmtoffset;
  32. extern int  __dstflag;
  33.  
  34. extern struct lconv __lconv;
  35.  
  36. char *setlocale(int category,const char *name)
  37. { static char *string=NULL;
  38.   size_t i,a,b;
  39.   struct Locale *vec[5];
  40.   unsigned char *s1,*s2,c;
  41.   
  42.   if(string!=NULL) /* Free string if possible */
  43.   { free(string);
  44.     string=NULL; }  
  45.  
  46.   if(category<0||category>5)
  47.     return NULL;
  48.  
  49.   if(category==LC_ALL)
  50.   { a=0;
  51.     b=4; }
  52.   else
  53.     a=b=category-1;
  54.  
  55.   if(name==NULL) /* return name of current locale */
  56.   { size_t s=0;
  57.     for(i=a;i<=b;i++)
  58.       if(__localevec[i]!=NULL)
  59.         s+=strlen(__localevec[i]->loc_LocaleName);
  60.       else
  61.         s++; /* "C" locale */
  62.  
  63.     if((string=malloc(s+b-a+1))==NULL)
  64.       return NULL;
  65.  
  66.     string[0]='\0';
  67.     for(i=a;i<=b;i++)
  68.     { if(__localevec[i]!=NULL)
  69.         strcat(string,__localevec[i]->loc_LocaleName);
  70.       else
  71.         strcat(string,"C");
  72.       if(i!=b)
  73.         strcat(string,"\n");
  74.     }
  75.     return string;
  76.   }
  77.  
  78.   if((string=malloc(strlen_plus_one(name)))==NULL) /* gets freed next time */
  79.     return NULL;
  80.   strcpy(string,name);
  81.  
  82.   s1=s2=string;
  83.   for(i=a;i<=b;i++)
  84.   { while(*s2!='\0'&&*s2!='\n')
  85.       s2++;
  86.     c=*s2;
  87.     *s2='\0';
  88.     if(LocaleBase==NULL||(s1[0]=='C'&&s1[1]=='\0')) /* This is the only place */
  89.       vec[i]=NULL;                         /* LocaleBase gets tested for NULL */
  90.     else
  91.       if((vec[i]=OpenLocale(s1[0]=='\0'?NULL:s1))==NULL)
  92.       { for(;i-->a;)
  93.           CloseLocale(vec[i]);
  94.         return NULL; }
  95.     *s2=c;
  96.     if(c=='\0')
  97.       s2=string;
  98.     s1=s2;
  99.   }
  100.  
  101.   for(i=a;i<=b;i++)
  102.   { if(__localevec[i]!=NULL)
  103.       CloseLocale(__localevec[i]);
  104.     __localevec[i]=vec[i];
  105.   }
  106.  
  107.   if(__localevec[LC_CTYPE-1]!=NULL)
  108.   { struct Locale *locale=__localevec[LC_CTYPE-1];
  109.     ctype[0]=0;
  110.     for(i=0;i<256;i++)
  111.       ctype[i+1]=((IsPrint(locale,i)&&!IsGraph(locale,i))?128:0)|
  112.                  (IsXDigit(locale,i)?64:0)|(IsCntrl(locale,i)?32:0)|
  113.                  (IsPunct(locale,i)?16:0)|(IsSpace(locale,i)?8:0)|
  114.                  (IsDigit(locale,i)?4:0)|(IsLower(locale,i)?2:0)|
  115.                  (IsUpper(locale,i)?1:0);
  116.     _ctype_=ctype;
  117.   }else
  118.     _ctype_=__ctype;
  119.  
  120.   if(__localevec[LC_MONETARY-1]!=NULL)
  121.   { struct Locale *locale=__localevec[LC_MONETARY-1];
  122.     __lconv.int_curr_symbol  =locale->loc_MonIntCS;
  123.     __lconv.currency_symbol  =locale->loc_MonCS;
  124.     __lconv.mon_decimal_point=locale->loc_MonDecimalPoint;
  125.     __lconv.mon_thousands_sep=locale->loc_MonGroupSeparator;
  126.     __lconv.mon_grouping     =locale->loc_MonFracGrouping;
  127.     __lconv.positive_sign    =locale->loc_MonPositiveSign;
  128.     __lconv.negative_sign    =locale->loc_MonNegativeSign;
  129.     __lconv.int_frac_digits  =locale->loc_MonIntFracDigits;
  130.     __lconv.frac_digits      =locale->loc_MonFracDigits;
  131.     __lconv.p_cs_precedes    =locale->loc_MonPositiveCSPos;
  132.     __lconv.p_sep_by_space   =locale->loc_MonPositiveSpaceSep;
  133.     __lconv.p_sign_posn      =locale->loc_MonPositiveSignPos;
  134.     __lconv.n_cs_precedes    =locale->loc_MonNegativeCSPos;
  135.     __lconv.n_sep_by_space   =locale->loc_MonNegativeSpaceSep;
  136.     __lconv.n_sign_posn      =locale->loc_MonNegativeSignPos;
  137.   }else
  138.   { __lconv.int_curr_symbol  ="";
  139.     __lconv.currency_symbol  ="";
  140.     __lconv.mon_decimal_point="";
  141.     __lconv.mon_thousands_sep="";
  142.     __lconv.mon_grouping     ="";
  143.     __lconv.positive_sign    ="";
  144.     __lconv.negative_sign    ="";
  145.     __lconv.int_frac_digits  =CHAR_MAX;
  146.     __lconv.frac_digits      =CHAR_MAX;
  147.     __lconv.p_cs_precedes    =CHAR_MAX;
  148.     __lconv.p_sep_by_space   =CHAR_MAX;
  149.     __lconv.p_sign_posn      =CHAR_MAX;
  150.     __lconv.n_cs_precedes    =CHAR_MAX;
  151.     __lconv.n_sep_by_space   =CHAR_MAX;
  152.     __lconv.n_sign_posn      =CHAR_MAX;
  153.   }
  154.  
  155.   if(__localevec[LC_NUMERIC-1]!=NULL)
  156.   { struct Locale *locale=__localevec[LC_NUMERIC-1];
  157.     __lconv.decimal_point=locale->loc_DecimalPoint;
  158.     __lconv.thousands_sep=locale->loc_GroupSeparator;
  159.   }else
  160.   { __lconv.decimal_point=".";
  161.     __lconv.thousands_sep=""; 
  162.   }
  163.   __decimalpoint=__lconv.decimal_point;
  164.  
  165.   if(__localevec[LC_TIME-1]!=NULL)
  166.     __gmtoffset=__localevec[LC_TIME-1]->loc_GMTOffset;
  167.   else
  168.     __gmtoffset=0;
  169.     
  170.   return (char *)name;
  171. }
  172.  
  173. void __initlocale(void)
  174. { ctype=malloc(257);
  175.   if(ctype==NULL)
  176.     exit(20);
  177.  
  178.   LocaleBase=(struct LocaleBase *)OpenLibrary(__localename,0); /* Don't give up if this failes */
  179.  
  180.   if(setlocale(LC_ALL,"")==NULL) /* Set the default locale */
  181.     exit(20);
  182. }
  183.  
  184. void __exitlocale(void)
  185. { int i;
  186.   for(i=0;i<5;i++)
  187.     if(__localevec[i]!=NULL)
  188.       CloseLocale(__localevec[i]);
  189.   
  190.   if(LocaleBase!=NULL)
  191.     CloseLibrary((struct Library *)LocaleBase);
  192. }
  193.  
  194. ADD2INIT(__initlocale,-10);
  195. ADD2EXIT(__exitlocale,-10);
  196.